﻿using BasicModuleWebApiJWTAuthorization.DBContextx;
using BasicModuleWebApiJWTAuthorization.Module;
using Microsoft.AspNetCore.Mvc;
using Microsoft.IdentityModel.Tokens;
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using System.Text;

namespace BasicModuleWebApiJWTAuthorization.Controllers
{
    [ApiController]
    [Route("api/[controller]")]
    public class JwtLoginController : ControllerBase
    {
        public MysqlDBContext mysqlDBContext { get; set; }

        public JwtLoginController(MysqlDBContext xmysqlDBContext)
        {
            this.mysqlDBContext = xmysqlDBContext;
        }

        [HttpPost("JwtLogin")]
        public IActionResult JwtLogin(T_User t_User)
        {
            BasicModuleWebApiJWTAuthorization.Model.User user = mysqlDBContext.users.Where(x => x.Name == t_User.Name && x.Passwd == t_User.Password).FirstOrDefault();
            //1.判断用户是否登录
            //if(t_User.Name == "xx"&& t_User.Password == "xxx") { }
            if (user != null)
            {
                Claim[] claims = new Claim[] {
                new Claim (JwtRegisteredClaimNames.Name,t_User.Name),
                //通过将jti设置为一个唯一的值（如UUID），JWT可以被用作一次性令牌。一旦令牌被使用或过期，它就不能再被接受，这减少了重放攻击的风险。
                //在创建JWT时，应使用一种能够生成唯一值的算法（如UUID）来设置jti字段
                //服务器应存储已使用的jti值，并在验证JWT时检查该值是否已被使用
                //结合JWT的过期时间（exp字段）和唯一标识符，可以进一步增强安全性。即使攻击者截获了令牌，它也会在短时间内过期，无法被重放。
                new Claim(JwtRegisteredClaimNames.Jti,Guid.NewGuid().ToString()),
                new Claim("Passwd",t_User.Password),
                new Claim("UserId",user.Id.ToString())
                  };
                //string issuer = null, 签发者 。生产token系统
                //string audience = null, 受用者 erp系统
                //IEnumerable<Claim> claims = null,  登录信息
                //DateTime? notBefore = null, 生成token时间
                //DateTime? expires = null,  token过期时间
                //SigningCredentials signingCredentials = null 签名凭证 【签名字符串】防止数据被篡改

                //SecurityKey 密钥
                //密钥：R2XMnd6TQdYRUmR0cCfL9fk651Fb3kDI
                SecurityKey securityKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("R2XMnd6TQdYRUmR0cCfL9fk651Fb3kDI"));
                //加密算法准备 非对称算法
                //签名凭证
                //SigningCredentials signingCredentials = new SigningCredentials(securityKey,SecurityAlgorithms.Sha256); //非对称算法
                SigningCredentials signingCredentials = new SigningCredentials(securityKey, SecurityAlgorithms.HmacSha256); //对称算法
                JwtSecurityToken jwtSecurityToken = new JwtSecurityToken(
                    issuer: "jwt",
                    audience: "BasicModuleWebApiJWTAuthorization",
                    claims: claims,
                    notBefore: DateTime.Now,
                    expires: DateTime.Now.AddMinutes(30.0),
                    signingCredentials: signingCredentials);
                //创建token 
                JwtSecurityTokenHandler handler = new JwtSecurityTokenHandler();
                //生成token
                string token = handler.WriteToken(jwtSecurityToken);
                return Ok(token);
            }
            else
                return Ok("登录失败");
        }
    }
}
